package scfg.utils.trainging_results;

import java.io.Serializable;
import java.math.MathContext;

import desposito6.math.*;

import java.util.LinkedList;
import java.util.List;

/**
 * The Class StatsDouble.
 */
public class StatsDouble implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4815613274339774756L;

	/** The avg. */
	private iDouble min, max, avg;

	/** The sd. */
	private iDouble sd;

	/** The vals. */
	private List<iDouble> vals;
	
	public List<iDouble> getVals(){
		return vals;
	}

	/**
	 * Gets the min.
	 * 
	 * @return the min
	 */
	public iDouble getMin() {
		return min;
	}

	/**
	 * Gets the max.
	 * 
	 * @return the max
	 */
	public iDouble getMax() {
		return max;
	}

	/**
	 * Gets the avg.
	 * 
	 * @return the avg
	 */
	public iDouble getAvg() {
		if (avg == null || avg.isNegative()) {
			iDouble sum = new MyBigDecimal(0, MathContext.DECIMAL128);
			for (iDouble d : vals)
				sum = sum.add(d);
			avg = sum.div(new MyBigDecimal(vals.size()));
		}
		return avg;
	}

	/**
	 * Gets the Standard Deviation.
	 * 
	 * @return the sD
	 */
	public iDouble getSD() {
		if (sd == null) {
			if (avg.isNegative())
				this.getAvg();
			iDouble temp = new MyBigDecimal(0, MathContext.DECIMAL128);
			for (iDouble d : vals){
				temp = temp.add(d.sub(avg).sqrt());
			}
			temp = temp.div(new MyBigDecimal(vals.size()));
			sd = temp.sqrt();
		}
		return sd;
	}

	/**
	 * Gets the range.
	 * 
	 * @return the range
	 */
	public iDouble getRange() {
		return max.sub(min);
	}

	/**
	 * Instantiates a new stats double.
	 */
	public StatsDouble() {
		min = new BigDouble(Double.MAX_VALUE);
		max = new BigDouble(Double.MIN_VALUE);
		avg = null;
		sd = null;
		vals = new LinkedList<iDouble>();
	}

	/**
	 * Adds the.
	 * 
	 * @param num
	 *            the num
	 */
	public void add(iDouble num) {
		if (num != null && (num.isZero() || num.isPositive())) {
			min = min == null ? num : min.min(num);
			max = max == null ? num : max.max(num);
			vals.add(num);
			if (sd != null) {
				avg = null;
				sd = null;
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "[ " + min + " : "
				+ this.getAvg() + " : "
				+ max + " ] (" + getSD() + ")";
	}
}
